#ifndef __FILESYS__
#define __FILESYS__

#include "../device/HardDisk.h"
#include "../lib/define.h"
#include "../lib/rtl.h"

#define SUPER_BLOCK_LOCATION 1
#define SUPER_BLOCK_MAGIC 0x53595346

#define FILE_INODE_MAGIC 0x454C4946

#define FILE_TYPE_UNKNOWN 0
#define FILE_TYPE_FOLDER 1
#define FILE_TYPE_DEFAULT 2

#define FILE_ATTR_KERNEL 0x00000001
#define FILE_ATTR_COMPRESSED 0x00000002
#define FILE_ATTR_ENCRYPTED 0x00000004
#define FILE_ATTR_HIDDEN 0x00000008
#define FILE_ATTR_SYSTEM 0x00000010

typedef struct SUPER_BLOCK {
  DWORD dwMagic;
  DWORD dwSectors;
  DWORD dwRoot;
  DWORD dwReserved[0x7D];
} * PSUPER_BLOCK, *LPSUPER_BLOCK;

typedef struct INODE {
  CHAR lpcName[0x40];
  DWORD dwLength;
  DWORD dwAttribute;
  DWORD dwType;
  DWORD dwSuper;
  DWORD dwMagic;
  DWORD dwAddress[0x6A];
  DWORD dwNext;
} * PINODE, *LPINODE;

void FsSuperBlockInitialize(void);

void FsInitialize(void);
DWORD FsGetRootNode(void);
DWORD FsAllocateSector(void);
void FsAllocateSectors(BOOLEAN (*lpfnCallback)(DWORD_PTR));
void FsFreeSector(DWORD dwAddress);
DWORD FsCreateFile(DWORD dwBase, const LPSTR lpszFilename);
DWORD FsOpenFile(DWORD dwBase, const LPSTR lpszFilename);
void FsDeleteFile(DWORD dwBase, const LPSTR lpszFilename);
void FsReadFile(DWORD dwFile, DWORD dwStart, LPVOID lpvBuffer, DWORD dwLength,
                LPDWORD dwBytesOfRead);
void FsWriteFile(DWORD dwFile, DWORD dwStart, const LPVOID lpvBuffer,
                 DWORD dwLength, LPDWORD dwBytesOfWrite);
DWORD FsCreateDirectory(DWORD dwBase, const LPSTR lpszDirname);
DWORD FsOpenDirectory(DWORD dwBase, const LPSTR lpszDirname);
void FsDeleteDirectory(DWORD dwBase, const LPSTR lpszDirname);
void FsFindAllFiles(DWORD dwBase, void (*lpfnCallback)(DWORD));

#endif
